/**
 * 公共工具函数库
 * 统一管理重复的工具函数，避免代码重复
 */

import { TIME_CONSTANTS } from '@/constants/messageTypes';

/**
 * 时间相关工具函数
 */
export const timeUtils = {
  /**
   * 比较时间（判断是否可以撤回/编辑）
   * @param {string|Date} date 要比较的日期
   * @param {number} timeLimit 时间限制（毫秒）
   * @returns {boolean} 是否在时间限制内
   */
  compareTime(date, timeLimit = TIME_CONSTANTS.RETRACT_TIME_LIMIT) {
    const providedDate = new Date(date);
    const currentDate = new Date();
    return providedDate.getTime() + timeLimit >= currentDate.getTime();
  },

  /**
   * 格式化时间
   * @param {string|Date} date 要格式化的日期
   * @param {string} format 格式字符串
   * @returns {string} 格式化后的时间字符串
   */
  formatTime(date, format = 'YYYY-MM-DD HH:mm:ss') {
    const d = new Date(date);
    const year = d.getFullYear();
    const month = String(d.getMonth() + 1).padStart(2, '0');
    const day = String(d.getDate()).padStart(2, '0');
    const hours = String(d.getHours()).padStart(2, '0');
    const minutes = String(d.getMinutes()).padStart(2, '0');
    const seconds = String(d.getSeconds()).padStart(2, '0');

    return format
      .replace('YYYY', year)
      .replace('MM', month)
      .replace('DD', day)
      .replace('HH', hours)
      .replace('mm', minutes)
      .replace('ss', seconds);
  },

  /**
   * 获取相对时间
   * @param {string|Date} date 要比较的日期
   * @returns {string} 相对时间字符串
   */
  getRelativeTime(date) {
    const now = new Date();
    const target = new Date(date);
    const diff = now - target;
    const seconds = Math.floor(diff / 1000);
    const minutes = Math.floor(seconds / 60);
    const hours = Math.floor(minutes / 60);
    const days = Math.floor(hours / 24);

    if (seconds < 60) return '刚刚';
    if (minutes < 60) return `${minutes}分钟前`;
    if (hours < 24) return `${hours}小时前`;
    if (days < 7) return `${days}天前`;
    return this.formatTime(date, 'MM-DD HH:mm');
  }
};

/**
 * 字符串相关工具函数
 */
export const stringUtils = {
  /**
   * 截断字符串
   * @param {string} str 要截断的字符串
   * @param {number} length 最大长度
   * @param {string} suffix 后缀
   * @returns {string} 截断后的字符串
   */
  truncate(str, length = 50, suffix = '...') {
    if (!str || str.length <= length) return str;
    return str.substring(0, length) + suffix;
  },

  /**
   * 首字母大写
   * @param {string} str 要转换的字符串
   * @returns {string} 首字母大写的字符串
   */
  capitalize(str) {
    if (!str) return '';
    return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
  },

  /**
   * 生成随机字符串
   * @param {number} length 长度
   * @returns {string} 随机字符串
   */
  randomString(length = 8) {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let result = '';
    for (let i = 0; i < length; i++) {
      result += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return result;
  },

  /**
   * 检查是否为空字符串
   * @param {any} value 要检查的值
   * @returns {boolean} 是否为空字符串
   */
  isEmpty(value) {
    return value === null || value === undefined || value === '';
  },

  /**
   * 检查是否为有效字符串
   * @param {any} value 要检查的值
   * @returns {boolean} 是否为有效字符串
   */
  isValidString(value) {
    return typeof value === 'string' && value.trim().length > 0;
  }
};

/**
 * 数组相关工具函数
 */
export const arrayUtils = {
  /**
   * 数组去重
   * @param {Array} arr 要去重的数组
   * @param {string} key 对象数组的去重键
   * @returns {Array} 去重后的数组
   */
  unique(arr, key = null) {
    if (!key) {
      return [...new Set(arr)];
    }
    const seen = new Set();
    return arr.filter(item => {
      const value = item[key];
      if (seen.has(value)) {
        return false;
      }
      seen.add(value);
      return true;
    });
  },

  /**
   * 数组分组
   * @param {Array} arr 要分组的数组
   * @param {string|Function} key 分组键或函数
   * @returns {Object} 分组后的对象
   */
  groupBy(arr, key) {
    return arr.reduce((groups, item) => {
      const groupKey = typeof key === 'function' ? key(item) : item[key];
      if (!groups[groupKey]) {
        groups[groupKey] = [];
      }
      groups[groupKey].push(item);
      return groups;
    }, {});
  },

  /**
   * 数组排序
   * @param {Array} arr 要排序的数组
   * @param {string} key 排序键
   * @param {string} order 排序顺序 'asc' | 'desc'
   * @returns {Array} 排序后的数组
   */
  sortBy(arr, key, order = 'asc') {
    return [...arr].sort((a, b) => {
      const aVal = a[key];
      const bVal = b[key];
      if (order === 'desc') {
        return bVal > aVal ? 1 : -1;
      }
      return aVal > bVal ? 1 : -1;
    });
  },

  /**
   * 数组分页
   * @param {Array} arr 要分页的数组
   * @param {number} page 页码（从1开始）
   * @param {number} pageSize 每页大小
   * @returns {Object} 分页结果
   */
  paginate(arr, page = 1, pageSize = 10) {
    const start = (page - 1) * pageSize;
    const end = start + pageSize;
    const items = arr.slice(start, end);
    return {
      items,
      total: arr.length,
      page,
      pageSize,
      totalPages: Math.ceil(arr.length / pageSize)
    };
  }
};

/**
 * 对象相关工具函数
 */
export const objectUtils = {
  /**
   * 深拷贝对象
   * @param {any} obj 要拷贝的对象
   * @returns {any} 拷贝后的对象
   */
  deepClone(obj) {
    if (obj === null || typeof obj !== 'object') return obj;
    if (obj instanceof Date) return new Date(obj);
    if (obj instanceof Array) return obj.map(item => this.deepClone(item));
    if (typeof obj === 'object') {
      const clonedObj = {};
      for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
          clonedObj[key] = this.deepClone(obj[key]);
        }
      }
      return clonedObj;
    }
  },

  /**
   * 合并对象
   * @param {Object} target 目标对象
   * @param {...Object} sources 源对象
   * @returns {Object} 合并后的对象
   */
  merge(target, ...sources) {
    return Object.assign({}, target, ...sources);
  },

  /**
   * 检查对象是否为空
   * @param {Object} obj 要检查的对象
   * @returns {boolean} 是否为空对象
   */
  isEmpty(obj) {
    return Object.keys(obj).length === 0;
  },

  /**
   * 获取嵌套属性值
   * @param {Object} obj 对象
   * @param {string} path 属性路径
   * @param {any} defaultValue 默认值
   * @returns {any} 属性值
   */
  get(obj, path, defaultValue = undefined) {
    const keys = path.split('.');
    let result = obj;
    for (const key of keys) {
      if (result === null || result === undefined || !result.hasOwnProperty(key)) {
        return defaultValue;
      }
      result = result[key];
    }
    return result;
  }
};

/**
 * 文件相关工具函数
 */
export const fileUtils = {
  /**
   * 格式化文件大小
   * @param {number} bytes 字节数
   * @returns {string} 格式化后的文件大小
   */
  formatFileSize(bytes) {
    if (bytes === 0) return '0 B';
    const k = 1024;
    const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
  },

  /**
   * 获取文件扩展名
   * @param {string} filename 文件名
   * @returns {string} 扩展名
   */
  getFileExtension(filename) {
    return filename.slice((filename.lastIndexOf('.') - 1 >>> 0) + 2);
  },

  /**
   * 检查文件类型
   * @param {string} filename 文件名
   * @param {Array} allowedTypes 允许的类型
   * @returns {boolean} 是否允许
   */
  isAllowedFileType(filename, allowedTypes) {
    const extension = this.getFileExtension(filename).toLowerCase();
    return allowedTypes.includes(extension);
  }
};

/**
 * 验证相关工具函数
 */
export const validationUtils = {
  /**
   * 验证邮箱
   * @param {string} email 邮箱地址
   * @returns {boolean} 是否有效
   */
  isValidEmail(email) {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email);
  },

  /**
   * 验证手机号
   * @param {string} phone 手机号
   * @returns {boolean} 是否有效
   */
  isValidPhone(phone) {
    const phoneRegex = /^1[3-9]\d{9}$/;
    return phoneRegex.test(phone);
  },

  /**
   * 验证URL
   * @param {string} url URL地址
   * @returns {boolean} 是否有效
   */
  isValidUrl(url) {
    try {
      new URL(url);
      return true;
    } catch {
      return false;
    }
  }
};

/**
 * 错误处理工具函数
 */
export const errorUtils = {
  /**
   * 创建错误对象
   * @param {string} message 错误消息
   * @param {string} code 错误代码
   * @param {any} data 错误数据
   * @returns {Object} 错误对象
   */
  createError(message, code = 'UNKNOWN_ERROR', data = null) {
    return {
      message,
      code,
      data,
      timestamp: new Date().toISOString()
    };
  },

  /**
   * 处理异步错误
   * @param {Function} asyncFn 异步函数
   * @returns {Promise} 处理后的Promise
   */
  handleAsyncError(asyncFn) {
    return async (...args) => {
      try {
        return await asyncFn(...args);
      } catch (error) {
        console.error('Async error:', error);
        throw this.createError(error.message, 'ASYNC_ERROR', error);
      }
    };
  }
};

/**
 * 性能相关工具函数
 */
export const performanceUtils = {
  /**
   * 创建性能计时器
   * @param {string} name 计时器名称
   * @returns {Function} 结束计时的函数
   */
  startTimer(name) {
    const startTime = performance.now();
    return () => {
      const endTime = performance.now();
      const duration = endTime - startTime;
      console.log(`${name} 耗时: ${duration.toFixed(2)}ms`);
      return duration;
    };
  },

  /**
   * 防抖函数
   * @param {Function} func 要防抖的函数
   * @param {number} wait 等待时间
   * @param {boolean} immediate 是否立即执行
   * @returns {Function} 防抖后的函数
   */
  debounce(func, wait, immediate = false) {
    let timeout;
    return function executedFunction(...args) {
      const later = () => {
        timeout = null;
        if (!immediate) func.apply(this, args);
      };
      const callNow = immediate && !timeout;
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);
      if (callNow) func.apply(this, args);
    };
  },

  /**
   * 节流函数
   * @param {Function} func 要节流的函数
   * @param {number} limit 时间间隔
   * @returns {Function} 节流后的函数
   */
  throttle(func, limit) {
    let inThrottle;
    return function executedFunction(...args) {
      if (!inThrottle) {
        func.apply(this, args);
        inThrottle = true;
        setTimeout(() => inThrottle = false, limit);
      }
    };
  }
};

// 导出所有工具函数
export default {
  timeUtils,
  stringUtils,
  arrayUtils,
  objectUtils,
  fileUtils,
  validationUtils,
  errorUtils,
  performanceUtils
};
